package business.player.Robot;

import BaseCommon.CommLog;
import business.global.club.Club;
import business.global.club.ClubMember;
import business.global.club.ClubMgr;
import business.global.room.UnionRoomMgr;
import business.global.room.base.AbsBaseRoom;
import business.global.room.base.AbsRoomPos;
import business.global.room.base.RobotRoom;
import business.global.room.key.RoomKeyMgr;
import business.global.shareroom.ShareRoom;
import business.global.shareroom.ShareRoomMgr;
import business.global.shareunion.ShareUnionListMgr;
import business.global.union.Union;
import business.global.union.UnionMgr;
import business.player.Player;
import business.player.PlayerMgr;
import business.rocketmq.bo.MqDissolveRoomNotifyBo;
import business.rocketmq.constant.MqTopic;
import business.shareplayer.SharePlayerMgr;
import cenum.RoomTypeEnum;
import com.ddm.server.common.Config;
import com.ddm.server.common.rocketmq.MqProducerMgr;
import com.ddm.server.common.task.ScheduledExecutorServiceMgr;
import com.ddm.server.common.utils.CommMath;
import com.ddm.server.common.utils.Lists;
import com.ddm.server.websocket.def.ErrorCode;
import com.google.gson.Gson;
import core.db.entity.clarkGame.UnionRoomConfigBO;
import core.db.other.Restrictions;
import core.db.service.clarkGame.UnionRoomConfigBOService;
import core.ioc.ContainerMgr;
import core.network.http.proto.SData_Result;
import jsproto.c2s.cclass.club.Club_define;
import jsproto.c2s.cclass.room.*;
import jsproto.c2s.iclass.club.CClub_Join;
import jsproto.c2s.iclass.club.CClub_SportsPointUpdate;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class RobotMgr2 {

    private static RobotMgr2 instance = new RobotMgr2();
    private Lock _lock = new ReentrantLock();// 锁对象

    HashMap<Long, RobotRoomConfig2> rebotConfigMap = new HashMap<Long, RobotRoomConfig2>();
    HashMap<Long, BaseRoomConfigure> configMap = new HashMap<Long, BaseRoomConfigure>();
    HashMap<Long, List<RobotRoom>> robotDeskMap = new HashMap<Long, List<RobotRoom>>();
    HashMap<Long, Long> timeMap = new HashMap<Long, Long>();
    HashMap<String, RobotRoom> roomKeyMap = new HashMap<String, RobotRoom>();
    LinkedList<Player> availableList;
    LinkedList<Player> availableClubList;
    LinkedList<Player> usedClubList = new LinkedList<>();
    Map<Long, Player> usedMap;


    int min_entertime = 1;
    int max_entertime = 50;
    int mintime = 0;
    int maxtime = 3;

    //获取所有俱乐部里面带机器人的 UnionRoomConfigBO，每次都重新获取，与现有的进行比较，如果有增加则立即增加，减少或者删除的等到解散之后就不自动创建新的了。
    //机器人列表用队列维护，一个在玩的列表，一个空闲的列表，玩完的或者新玩的自动从一个队列加入到另外一个队列，同时维护ShareRoomMgr

    public final int limitID = 69000000;

    public static RobotMgr2 getInstance() {
        return instance;
    }

    public void init() {
        ///loadRobots("robots.txt");
        final Random random = new Random();
        ScheduledExecutorServiceMgr.getInstance().getScheduledFuture(() -> {
            PlayerMgr.getInstance().getAllRobotPlayers();
            //UnionRoomMgr.getInstance().queryExistEmptyPos();
            try {
                if(availableList==null){
                    availableList = Lists.newLinkedList(PlayerMgr.getInstance().getAllRobotPlayers());
                    availableClubList = Lists.newLinkedList(PlayerMgr.getInstance().getAllClubRobotPlayers());
                    usedMap = new HashMap<>();
                }
                //查看是否桌子数没达到设置，如果没有则创建假桌子
                Map<Long, Union> unionMap = UnionMgr.getInstance().getUnionListMgr().getUnionMap();
                for (Long key:unionMap.keySet()) {
                    Union union = unionMap.get(key);
                    List<UnionRoomConfigBO> unionRoomConfigBOList = ContainerMgr.get().getComponent(UnionRoomConfigBOService.class).findAll(Restrictions.eq("unionId", union.getUnionBO().getId()));
                    for (UnionRoomConfigBO unionRoomConfigBO:unionRoomConfigBOList) {
                        BaseRoomConfigure baseRoomConfigure = union.getBaseRoomConfigure(unionRoomConfigBO);
                        if(baseRoomConfigure!=null
                            &&baseRoomConfigure.getBaseCreateRoom()!=null
                                &&baseRoomConfigure.getBaseCreateRoom().getRobotRoomCfg2()!=null
                                &&baseRoomConfigure.getBaseCreateRoom().getRobotRoomCfg2().getDeskNum()>0){
                            RobotRoomConfig2 robotRoomConfig2 = baseRoomConfigure.getBaseCreateRoom().getRobotRoomCfg2();
                            rebotConfigMap.put(unionRoomConfigBO.getId(),robotRoomConfig2);
                            configMap.put(unionRoomConfigBO.getId(), baseRoomConfigure);
                            baseRoomConfigure.getBaseCreateRoom().setGameIndex(unionRoomConfigBO.getId());
                        }
                    }

                }

                for (Long key:rebotConfigMap.keySet()) {
                    RobotRoomConfig2 robotRoomConfig2 = rebotConfigMap.get(key);
                    BaseRoomConfigure baseRoomConfigure = configMap.get(key);
                    List<RobotRoom> roomList = robotDeskMap.get(key);
                    if(roomList == null){
                        roomList = new ArrayList<>();
                        robotDeskMap.put(key, roomList);
                    }
                    if(roomList.size()<robotRoomConfig2.getDeskNum()){
                        CreateFakeTable(key, baseRoomConfigure,random);
                    }
                }

                for (Long key:rebotConfigMap.keySet()) {
                    RobotRoomConfig2 robotRoomConfig2 = rebotConfigMap.get(key);
                    BaseRoomConfigure baseRoomConfigure = configMap.get(key);
                    List<RobotRoom> roomList = robotDeskMap.get(key);
                    List<RobotRoom> roomList2 = new ArrayList<>();
                    for (RobotRoom robotRoom : roomList) {
                        if(robotRoom.getEndTime()<System.currentTimeMillis()){
                            if(robotRoom.getCurSetID() == baseRoomConfigure.getBaseCreateRoom().getSetCount()){
                                ShareRoomMgr.getInstance().doDissolveRoom(ShareRoomMgr.getInstance().getShareRoomByKey(robotRoom.getRoomKey()));
                                //MqDissolveRoomNotifyBo bo =  new MqDissolveRoomNotifyBo(robotRoom.getRoomKey(), ShareRoomMgr.getInstance().getShareRoomByKey(robotRoom.getRoomKey()).getCurShareNode());
                                //ShareRoomMgr.getInstance().removeShareRoom(robotRoom.getRoomKey());
                                // 通知解散房间
                                //MqProducerMgr.get().send(MqTopic.DISSOLVE_ROOM_NOTIFY, bo);

                                roomList2.add(robotRoom);
                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            Thread.sleep(1000);
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        }
                                        roomKeyMap.remove(robotRoom.getRoomKey());
                                    }
                                }).start();
                                List<RoomPosInfoShort> roomPosInfoShorts = robotRoom.getRoomPosMgr().getRoomPosInfoShortList();
                                for (int i = 0; i < roomPosInfoShorts.size(); i++) {
                                    availableList.add(usedMap.remove(roomPosInfoShorts.get(i).getPid()));
                                }
                            }else{
                                if(robotRoom.getCurSetID()==0){
                                    robotRoom.getRoomTyepImpl().setLock(false);
                                    robotRoom.startGame(robotRoom.getRoomPosMgr().getPosList().get(0).getPid());
                                    for (AbsRoomPos absRoomPos:robotRoom.getRoomPosMgr().getPosList()) {
                                        robotRoom.getRoomTyepImpl().roomPlayerChange(absRoomPos);
                                    }

                                }
                                long endTime = System.currentTimeMillis();
                                if(robotRoomConfig2.getMaxTime()<=robotRoomConfig2.getMinTime()){
                                    endTime = robotRoomConfig2.getMinTime()*60*1000;
                                }else{
                                    endTime += (robotRoomConfig2.getMaxTime()+random.nextInt((robotRoomConfig2.getMaxTime()-robotRoomConfig2.getMinTime())*60))*1000;
                                }
                                if(endTime<=0){
                                    endTime = 1*60*1000;
                                }
                                robotRoom.setEndTime(endTime);
                                robotRoom.setCurSetID(robotRoom.getCurSetID()+1);
                                robotRoom.getRoomTyepImpl().roomSetIDChange();
                                ShareRoomMgr.getInstance().updateSetId(robotRoom.getRoomKey(),robotRoom.getCurSetID());
                            }
                        }
                    }
                    roomList.removeAll(roomList2);
                }

            } catch (Exception e) {
                CommLog.error("[RobotMgr] error:{}",e.getMessage(), e);
            }

//            ClubMember opClubMember = ClubMgr.getInstance().getClubMemberMgr().find(req.getOpPid(), req.getClubId(), Club_define.Club_Player_Status.PLAYER_JIARU);
//            opClubMember.getClubMemberBO().getSportsPoint()
//            final CClub_SportsPointUpdate req = new Gson().fromJson(message, CClub_SportsPointUpdate.class);//上下分
//            SData_Result result = ClubMgr.getInstance().getClubMemberMgr().execSportsPointUpdate(req,player.getPid(),player);
//            this.getClubMemberMgr().onInsertClubMember(player, club, Club_define.Club_MINISTER.Club_MINISTER_GENERAL.value(), club.clubListBO.getOwnerID())
//            ClubMgr.getInstance().onJoinClub(player, req);  CClubJoin
            // 检查加入
//            result = UnionMgr.getInstance().getUnionMemberMgr().checkJoinUnion((Union) room.getRoomTyepImpl().getSpecialRoom(), clubId, this.player, room.getRoomPidAll(), room.getBaseRoomConfigure().getBaseCreateRoom());
//            getUnionBO().getClubId() 根据clubid和playerid判断是否属于这个朋友圈   朋友圈添加机器人，初始化积分
//            player增加clubid对应已经分配到哪个俱乐部，isandroid=2是陪玩机器人，1是暖场机器人
//            加入房间需要判断入场分，对于低于入场分的需要给上分，对于赢的分数，如果太多也可以下分
//            UnionMgr.getInstance().getUnionMemberMgr().checkJoinUnion入场分检查  PlayerUnionRoom？？？
//
//            try {
//                Map<Long, Union> map = ShareUnionListMgr.getInstance().getAllUnion();
//                Collection<Union> unionSet = ShareUnionListMgr.getInstance().getAllUnion().values();
////                Collection<Union> unionSet = UnionMgr.getInstance().getUnionListMgr().getUnionMap().values();
////                Collection<Club> clubSet = ClubMgr.getInstance().getClubListMgr().getClubMap().values();
//                for (Map.Entry<Long,Union> entry: map.entrySet()) {
//                    Union union = entry.getValue();
//                    if (entry.getKey()==101233){
//                        System.out.println(22);
//                        System.out.println(union.getUnionBO().getRobotNum());
//                    }
//                    if(union.getUnionBO().getRobotNum()>0){
//                        long clubId = union.getUnionBO().getClubId();
//                        List<Player> players = PlayerMgr.getInstance().getAllClubRobotPlayers();
//                        long num = players.stream().filter(p -> p.getPlayerBO().getClubId()==clubId).count();
//                        if(num<union.getUnionBO().getRobotNum()){
//                            addPlayers2ClubUnion(union.getUnionBO().getRobotNum() - num,union,union.getUnionBO().getRobotInitScore());
//                        }
//
//                        List<ShareRoom> roomList = ShareRoomMgr.getInstance().roomUnionValues(RoomTypeEnum.UNION, union.getUnionBO().getId(), new ArrayList<>() , 0, 0,0);
//
//                        for (ShareRoom room : roomList) {
//                            if (null == room) {
//                                continue;
//                            }
//                            // 房间里面的空位
//                            int emptyPosSize = room.getEmptyPosCount();
//                            int fullPosSize = room.getPosList().size();
//                            if (0 < emptyPosSize&&emptyPosSize<fullPosSize) {
////                                int androidPosSize = (int) room.getPosList().stream().filter((x) -> x.getPlayer()!=null&&x.getPlayer().getAndroid() == 1).count();
//
//                                int min_entercnt = 1;
//                                int max_entercnt = fullPosSize - 1;
//                                int s = random.nextInt(max_entercnt) % (max_entercnt - min_entercnt + 1) + min_entercnt;
//                                s = s < emptyPosSize ? s : emptyPosSize;
//                                for (int i = 0; i < s; i++) {
//                                    for (int j = 0; j < availableClubList.size(); j++) {
//                                        Player rber = availableClubList.get(j);
//                                        if (null != rber && rber.getPlayerBO().getClubId()==room.getBaseRoomConfigure().getBaseCreateRoom().getClubId()) {
//                                            boolean enter = rber.onEnterRoom(room.getRoomId());
////                                        SData_Result enterResult = UnionRoomMgr.getInstance().findAndEnter(room, rber.getPid(), true);
//                                            if(enter){
//                                                availableClubList.remove(j);
//                                                usedClubList.add(rber);//结束之后需要从列表里面拿出来
//                                            }else{
//                                                //availableClubList.add(rber);
//                                            }
//                                            break;
//                                        }
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//
//            } catch (Exception e) {
//                CommLog.error("[RobotMgr] error:{}",e.getMessage(), e);
//            }
//
//            try {
//                List<AbsBaseRoom> querys = UnionRoomMgr.getInstance().queryExistEmptyPos();
//                if (null != querys) {
//                    for (AbsBaseRoom room : querys) {
//                        if (null == room) {
//                            continue;
//                        }
//                        // 房间里面的空位
//                        int emptyPosSize = room.getRoomPosMgr().getEmptyPosCount();
//                        int fullPosSize = room.getRoomPosMgr().getFullPosCount();
//                        if (0 < emptyPosSize) {
//                            int androidPosSize = (int) room.getRoomPosMgr().getPosList().stream().filter((x) -> x.getPlayer()!=null&&x.getPlayer().getAndroid() == 1).count();
//
//                            int min_entercnt = 1;
//                            int max_entercnt = fullPosSize - 1;
//                            int s = random.nextInt(max_entercnt) % (max_entercnt - min_entercnt + 1) + min_entercnt;
//                            s = s < emptyPosSize ? s : emptyPosSize;
//                            for (int i = 0; i < s; i++) {
//                                Player rber = availableClubList.pop();
//                                if (null != rber && rber.getPlayerBO().getClubId()==room.getBaseRoomConfigure().getBaseCreateRoom().getClubId()) {
//                                    SData_Result enterResult = UnionRoomMgr.getInstance().findAndEnter(room, rber.getPid(), true);
//                                    if(enterResult.getCode()== ErrorCode.Success){
//                                        usedClubList.add(rber);//结束之后需要从列表里面拿出来
//                                    }else{
//                                        availableClubList.add(rber);
//                                    }
//                                    break;
//                                }
//                            }
//                        }
//                    }
//                }
//            } catch (Exception e) {
//                CommLog.error("[RobotMgr] error:{}",e.getMessage(), e);
//            }


        }, 60000, 2000);
    }

    private void addPlayers2ClubUnion(long num, Union union, int robotInitScore) {

        Club club = ClubMgr.getInstance().getClubListMgr().findClub(union.getUnionBO().getClubId());
        List<Player> players = PlayerMgr.getInstance().getAllClubRobotPlayers();
        for (Player player:players){
            if(num<=0){
                break;
            }
            if(player.getPlayerBO().getClubId()==0){
                CClub_Join req = CClub_Join.make(club.getClubListBO().getClubsign());
                SData_Result result = ClubMgr.getInstance().onJoinClub(player, req,true);
                if(ErrorCode.Success.equals(result.getCode())||ErrorCode.CLUB_EXIST_JIARU.equals(result.getCode())) {
                    num--;
                    player.getPlayerBO().saveClubId((int) union.getUnionBO().getClubId());
                    final CClub_SportsPointUpdate req2 = new CClub_SportsPointUpdate(club.getClubListBO().getId(),player.getPid(),0,robotInitScore);//上下分
                    result = ClubMgr.getInstance().getClubMemberMgr().execSportsPointUpdate(req2,player.getPid(),player);
                }
            }
        }
    }

    private void CreateFakeTable(Long key, BaseRoomConfigure baseRoomConfigure, Random random) {
        RobotRoomConfig2 robotRoomCfg2 = baseRoomConfigure.getBaseCreateRoom().getRobotRoomCfg2();
        //RoomKeyMgr.getInstance().getNewKey()
        Player owner = availableList.pop();
        RobotRoom room = new RobotRoom(baseRoomConfigure,RoomKeyMgr.getInstance().getNewKey(),owner.getPid());

        //共享更新
        if (Config.isShare()) {
            room.setCurSetID(0);
            List<AbsRoomPos> roomPosList = room.getRoomPosMgr().getPosList();
            //List<RoomPosInfoShort> roomPosInfoShorts = room.getRoomPosMgr().getRoomPosInfoShortList();
            for (int i = 0; i < roomPosList.size(); i++) {
                if(i>0){
                    owner = availableList.pop();
                }
                AbsRoomPos roomPosInfoShort = roomPosList.get(i);
                roomPosInfoShort.setPosID(i);
                roomPosInfoShort.setClubID(0);
                roomPosInfoShort.setPid(owner.getPid());
                roomPosInfoShort.setHeadImageUrl(owner.getHeadImageUrl());
                roomPosInfoShort.setName(owner.getName());
                roomPosInfoShort.setPlayer(owner);
                SharePlayerMgr.getInstance().addAllSharePlayer(owner);
                owner.onEnterRoom(room.getRoomID());
                usedMap.put(owner.getPid(),owner);
            }
            long endTime = System.currentTimeMillis();
            //endTime += (robotRoomCfg2.getMaxTime()+random.nextInt((robotRoomCfg2.getMaxTime()-robotRoomCfg2.getMinTime())*60))*1000;
            room.setEndTime(endTime);
            robotDeskMap.get(key).add(room);
            robotDeskMap.put(key,robotDeskMap.get(key));
            roomKeyMap.put(room.getRoomKey(),room);
            //ShareRoomMgr.getInstance().addShareRoom(room);

        }
    }

    public HashMap<String, RobotRoom> getRoomKeyMap() {
        return roomKeyMap;
    }
}
